﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using NUnit.Framework;
using PassBag;
using PassBag.Logic;
using PassBag.Utils;

namespace TestPassBag {
    [TestFixture, Description ("Test the password policy generation")]
    public class TestPasswordPolicy {
        [Test, Description ("Test the number of digit, special char and chars")]
        public void TestPasswordLength () {
            int NUMBER_OF_TEST = 20;
            int numberOfDigits = 3;
            int numberOfSpecialChars = 2;
            int maxLen = 8;

            for (int i = 0; i < NUMBER_OF_TEST; i++) {
                PasswordPolicy policy = new PasswordPolicy (numberOfDigits, numberOfSpecialChars, maxLen);

                string password = policy.GeneratePassword ();
                int countNumberOfDigits = 0;
                int countNumberOfSpecialChars = 0;

                ExtractPasswordInfo (password, out countNumberOfDigits, out countNumberOfSpecialChars);

                Assert.AreEqual (numberOfDigits, countNumberOfDigits);
                Assert.AreEqual (numberOfSpecialChars, countNumberOfSpecialChars);
                Assert.GreaterOrEqual (password.Length, numberOfDigits + numberOfSpecialChars + PasswordPolicy.MIN_CHARS);

                Assert.LessOrEqual (password.Length, maxLen); 
            }
        }

        [Test, Category("CanFail") , Description ("Test the Levenshtein distance between passwords")]
        public void TestPasswordSimilarity () {
            int numberOfDigits = 3;
            int numberOfSpecialChars = 2;
            int maxLen = 8;

            PasswordPolicy pass = new PasswordPolicy (numberOfDigits, numberOfSpecialChars, maxLen);

            string s1 = pass.GeneratePassword ();
            System.Threading.Thread.Sleep (DateTime.Now.Second);
            string s2 = pass.GeneratePassword ();

            int distance = StringSimilarity.DistanceBetween (s1, s2);

            Assert.IsTrue (distance > 4);
           
        }

        private void ExtractPasswordInfo (string password, out int digitCount, out int specialCharsCount) {
            digitCount = specialCharsCount = 0;

            for (int i = 0; i < password.Length; i++) {
                if (Char.IsDigit(password[i])) {
                    digitCount++;    
                }
                else if (! Char.IsLetterOrDigit(password[i])) {
                    specialCharsCount++;
                }
            }
        }

    }
}
